package com.xctech.yace.swing.tab;

import com.eltima.components.ui.DatePicker;
import com.xctech.yace.mapper.MetaDataMapper;
import com.xctech.yace.pojo.SelectCollectCondition;
import com.xctech.yace.service.FileService;
import com.xctech.yace.service.KafkaSelectCollectRecived;
import com.xctech.yace.service.TradeO32Service;
import com.xctech.yace.single.RecivedDataManger;;
import com.xctech.yace.swing.subTab.MonitorSwing;
import com.xctech.yace.thread.ConsumerSelectCollectThread;
import com.xctech.yace.util.DateUtil;
import com.xctech.yace.util.FormatUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.kafka.clients.consumer.ConsumerRecord;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.util.*;
import java.util.List;

import static com.xctech.yace.swing.ConfigValue.*;
import static com.xctech.yace.swing.ConfigValue.height;
import static com.xctech.yace.swing.FatherSwing.productPropties;
import static com.xctech.yace.swing.InitFileConfig.topicMap;
import static javax.swing.JOptionPane.*;

@Slf4j
public class SelectCollectTabSwing {

    public static String title = "挑选收集";

    public static String savePath = "conf/result/";

    public static Boolean isSaveFile;
    public static Integer index = 1;
    public static Map<Integer,Tuple2<JLabel, JTextField>> indexComponentMap = new HashMap<>();

    public static Boolean isMonitor = false;
    //界面刷新线程
    public static Thread flush = null;
    //监听线程
    public static Thread reciving = null;
    //接收类
    public static KafkaSelectCollectRecived recived = new KafkaSelectCollectRecived();

    //db mapper
    public static MetaDataMapper mapper = TradeO32Service.initMetaData();

    //操作时间-文件名
    public static String operTime = DateUtil.getTodayTime();

    public static JSplitPane genSelectCollectSplitPanel() {
        //发送画板
        JPanel send = new JPanel();
        //监控画板
        JPanel monitor = new JPanel();

        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, send, monitor);
        splitPane.setDividerLocation(1100);

        placeComponentsSelectCollectRight(send);
        MonitorSwing.placeComponentsRight(monitor);
        return splitPane;
    }

    private static DatePicker getDatePicker(int x,int y,int width,int height) {
        final DatePicker datepick;
        // 格式
        String DefaultFormat = "yyyy-MM-dd HH:mm:ss";
        // 当前时间
        Date date = new Date();
        // 字体
        Font font = new Font("Times New Roman", Font.BOLD, 14);

        Dimension dimension = new Dimension(width, height);

        int[] hilightDays = { };

        int[] disabledDays = { };

        datepick = new DatePicker(date, DefaultFormat, font, dimension);

        datepick.setLocation(x, y);
        datepick.setBounds(x, y, width, height);
        // 设置一个月份中需要高亮显示的日子
        datepick.setHightlightdays(hilightDays, Color.red);
        // 设置一个月份中不需要的日子，呈灰色显示
        datepick.setDisableddays(disabledDays);
        // 设置国家
        datepick.setLocale(Locale.CHINA);
        // 设置时钟面板可见
        datepick.setTimePanleVisible(true);
        return datepick;
    }

    private static Tuple2<JLabel,JTextField> getTextField(int index, int x, int y, int width, int height){
        JLabel conditionLabel = new JLabel("关键字:" + index);
        conditionLabel.setBounds(x,y,65,height);
        JTextField conditionField = new JTextField();
        conditionField.setBounds(x+60,y,width,height);
        return Tuple2.of(conditionLabel,conditionField);
    }

    public static void placeComponentsSelectCollectRight(JComponent panel){
        /* 布局部分我们这边不多做介绍
         * 这边设置布局为 null
         */
        panel.setLayout(null);

        Properties properties = productPropties();
        String ipport = properties.getProperty("bootstrap.servers");

        //主题
        JComboBox topicBox=new JComboBox();    //创建JComboBox
        topicBox.addItem("--自定义主题--");    //向下拉列表中添加一项
        topicMap.entrySet().stream().forEach(topics->{
            topics.getValue().stream().forEach(topic->{
                topicBox.addItem(topic);
            });
        });
        topicBox.setBounds(15,20,sfiledW+50,height);
        topicBox.setToolTipText(ipport);
        panel.add(topicBox);

        JTextField topicText = new JTextField(20);
        topicText.setBounds(15+sfiledW+space+40,20,200,height);
        topicText.setFont(new Font("Courier",Font.BOLD,13));
        topicText.setToolTipText(ipport);
        panel.add(topicText);

        //分区
        JComboBox partitionBox = new JComboBox();    //创建JComboBox
        partitionBox.addItem("----分区数----");    //向下拉列表中添加一项
        for(int i= 0;i< 100 ;i++){
            partitionBox.addItem(i+1);
        }
        partitionBox.setBounds(400,20,sfiledW,height);
        partitionBox.setToolTipText(ipport);
        panel.add(partitionBox);

        //是否按规则将信息保存到文件中
        JLabel isSaveLabel = new JLabel("是否保存文件：");
        isSaveLabel.setToolTipText("路径:"+savePath+"主题_"+ DateUtil.getTodayTime());
        isSaveLabel.setBounds(679, 20,90,height);
        panel.add(isSaveLabel);
        ButtonGroup bg = new ButtonGroup(); // 创建单选按钮组
        JRadioButton YButton = new JRadioButton("Y");
        YButton.setBounds(779, 20,50,height);
        JRadioButton NButton = new JRadioButton("db");
        NButton.setBounds(829, 20,50,height);
        bg.add(YButton);
        bg.add(NButton);
        panel.add(YButton);
        panel.add(NButton);

        //关键字条件且|或
        JLabel conditionLabel = new JLabel("逻辑条件：");
        conditionLabel.setToolTipText("关键字条件全且|全或");
        conditionLabel.setBounds(15, 20+height+5,65,height);
        panel.add(conditionLabel);
        ButtonGroup conditionBg = new ButtonGroup(); // 创建单选按钮组
        JRadioButton andButton = new JRadioButton("& &");
        andButton.setBounds(75, 20+height+5,50,height);
        JRadioButton orButton = new JRadioButton("| |");
        orButton.setBounds(125, 20+height+5,50,height);
        conditionBg.add(andButton);
        conditionBg.add(orButton);
        panel.add(andButton);
        panel.add(orButton);

        //开始时间
        JLabel startName = new JLabel("开始时间:");
        startName.setBounds(120+177,20+height+5,100,height);
        panel.add(startName);
        final DatePicker startTime = getDatePicker(367,20+height+5,177,height);
        panel.add(startTime);

        //结束时间
        JLabel endName = new JLabel("结束时间:");
        endName.setBounds(679,20+height+5,100,height);
        panel.add(endName);
        final DatePicker endTime = getDatePicker(679+70,20+height+5,177,height);
        panel.add(endTime);

        //文本框动态递增
        JButton addButton = new JButton("新增");
        addButton.setBounds(15,20+height*2+space,60,30);
        panel.add(addButton);
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(index > 20){
                    JOptionPane.showMessageDialog(null,"关键字条件最多不超过20","key count",WARNING_MESSAGE);
                    return;
                }
                Tuple2<JLabel, JTextField> tuple2 = getTextField(index, 15, (60+height*2+space)+(index-1)*35,210, 30);
                panel.add(tuple2.f0);
                panel.add(tuple2.f1);
                SwingUtilities.updateComponentTreeUI(panel);//添加或删除组件后,更新窗口
                index++;
                indexComponentMap.put(index,tuple2);
            }
        });

        JButton delButton = new JButton("删除");
        delButton.setBounds(105,20+height*2+space,60,30);
        panel.add(delButton);
        delButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(index <= 1){
                    JOptionPane.showMessageDialog(null,"关键字条件最少不低于0","key count",WARNING_MESSAGE);
                    return;
                }
                if(indexComponentMap.size() != 0){
                    Tuple2<JLabel, JTextField> tuple2 = indexComponentMap.get(index);
                    if(tuple2 != null){
                        panel.remove(tuple2.f0);
                        panel.remove(tuple2.f1);
                        SwingUtilities.updateComponentTreeUI(panel);//添加或删除组件后,更新窗口
                        indexComponentMap.remove(index);
                        index--;
                    }
                }
            }
        });

        JButton resetButton = new JButton("重置");
        resetButton.setBounds(195,20+height*2+space,60,30);
        panel.add(resetButton);


        // 发送按钮
        JButton startButton = new JButton("开始收集");
        startButton.setBounds(960,20,sfiledW,height*2+5);
        startButton.setToolTipText(ipport);
        panel.add(startButton);

        //message按钮
        JTextArea area = new JTextArea();
        JScrollPane scrollArea = new JScrollPane(area);

        scrollArea.setMaximumSize(scrollArea.getPreferredSize());
        scrollArea.setBounds(120+177,20+height*2+space,775,870);
        area.setFont(new Font("幼圆",Font.BOLD,15));

        scrollArea.setHorizontalScrollBarPolicy(
                JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollArea.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        panel.add(scrollArea);

        area.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_DELETE){
                    System.out.println("清空area界面");
                    area.setText("");
                }
                //组合按键  ctrl+f
                if((e.getKeyCode() == KeyEvent.VK_F) && e.isControlDown()){
                    System.out.println("ctrl+f 暂未实现");
                }
            }
        });

        resetButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //锁按钮
                if(isMonitor){
                    isMonitor = false;
                    startButton.setEnabled(true);
                    topicText.setEnabled(true);
                    topicBox.setEnabled(true);
                    partitionBox.setEnabled(true);
                    YButton.setEnabled(true);
                    NButton.setEnabled(true);
                    andButton.setEnabled(true);
                    orButton.setEnabled(true);
                    delButton.setEnabled(true);
                    addButton.setEnabled(true);
                    startTime.setEnabled(true);
                    endTime.setEnabled(true);
                    for(Tuple2<JLabel, JTextField> tuple2:indexComponentMap.values()){
                        tuple2.f1.setEnabled(true);
                    }

                    if(flush != null){
                        flush.stop();
                    }
                    if(reciving != null){
                        reciving.stop();
                    }
                }
                int isClear = showConfirmDialog(null, "               是否重置条件值？", "重置", YES_NO_OPTION);
                if(isClear == 0){
                    //提示是否清空
                    if(indexComponentMap.size() != 0){
                        for(Tuple2<JLabel, JTextField> t:indexComponentMap.values()){
                            panel.remove(t.f0);
                            panel.remove(t.f1);
                        }
                        SwingUtilities.updateComponentTreeUI(panel);//添加或删除组件后,更新窗口
                        index = 1;
                        indexComponentMap.clear();
                        if(indexComponentMap.isEmpty()){
                            JOptionPane.showMessageDialog(null,"关键字条件重置成功!","key",WARNING_MESSAGE);
                        }
                    }
                }

            }
        });

        topicBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                topicText.setText("");//重置
                if(topicBox.getSelectedIndex()!=0){
                    String topic = topicBox.getSelectedItem().toString().trim();
                    topicText.setText(topic);
                }
            }
        });

        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                //开多主题监听设置,数据隔离
                String topicStr = topicText.getText();
                String[] topicArray = topicStr.split(",");
                //开启监听
                if("".equals(topicStr)){
                    System.out.println("主题为空");
                    JOptionPane.showMessageDialog(null,"主题为空","kafkaSend",WARNING_MESSAGE);
                    return;
                }

                //锁按钮
                if(!isMonitor){
                    isMonitor = true;
                    startButton.setEnabled(false);
                    topicText.setEnabled(false);
                    topicBox.setEnabled(false);
                    partitionBox.setEnabled(false);
                    YButton.setEnabled(false);
                    NButton.setEnabled(false);
                    andButton.setEnabled(false);
                    orButton.setEnabled(false);
                    delButton.setEnabled(false);
                    addButton.setEnabled(false);
                    startTime.setEnabled(false);
                    endTime.setEnabled(false);
                    for(Tuple2<JLabel, JTextField> tuple2:indexComponentMap.values()){
                        tuple2.f1.setEnabled(false);
                    }
                    operTime = DateUtil.getTodayTime();

                    SelectCollectCondition condition = new SelectCollectCondition();
                    condition.setTopics(topicArray);
                    int selectedIndex = partitionBox.getSelectedIndex();
                    if(selectedIndex == 0){
                        JOptionPane.showMessageDialog(null,"分区数为0","kafkaCollectPartition",WARNING_MESSAGE);
                        return;
                    }
                    condition.setPartition(selectedIndex);
                    Boolean isSave = true;//默认保存
                    if(NButton.isSelected()){
                        isSave = false;
                    }
                    condition.setIsSaveFileFormat(isSave);
                    isSaveFile = isSave;
                    String logic = "&&";//默认是&&
                    if(orButton.isSelected()){
                        logic = "||";
                    }
                    condition.setLogic(logic);
                    String startTimeText = startTime.getText();
                    String endTimeText = endTime.getText();
                    if(startTimeText != null && endTimeText != null){
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        try {
                            condition.setStartTimestamp(sdf.parse(startTimeText).getTime());
                            condition.setEndTimestamp(sdf.parse(endTimeText).getTime());
                        } catch (ParseException ex) {
                            ex.printStackTrace();
                        }
                    }
                    List<String> keys = new ArrayList<>();
                    for(Tuple2<JLabel, JTextField> tuple2:indexComponentMap.values()){
                        String key = tuple2.f1.getText().trim();
                        keys.add(key);
                    }
                    condition.setKeys(keys);

                    List<ConsumerSelectCollectThread> consumerThreads = recived.reciveConsumer(condition);
                    for(ConsumerSelectCollectThread c:consumerThreads){
                        reciving = new Thread(c);
                        reciving.start();
                    }

                    //读
                    flush = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            RecivedDataManger<ConsumerRecord<String, String>> instance = RecivedDataManger.getInstance();
                            Integer i = 0;
                            Integer j = 0;
                            while (true) {
                                Queue<ConsumerRecord<String, String>> read = instance.getRead();
                                Queue<ConsumerRecord<String, String>> write = instance.getWrite();
                                while (read.isEmpty()) {
                                    //只有当读队列为空且写队列大小超过1000时才进行交换。这样做的好处一是可以避免交换频率过高，二是保证一次获取一定量的实例
                                    try {
                                        if (write.size() >= 1) {
                                            instance.swap();
                                        } else {
                                            String text = area.getText();
                                            if (!"".equals(text) && i >= 10000) {
                                                //重置监听和清除数据
                                                area.setText("");
                                                i = 0;
                                            }
                                            Thread.sleep(1000);
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                    read = instance.getRead();
                                }
                                //批量消费
                                while (!read.isEmpty()) {
                                    ConsumerRecord<String, String> poll = read.poll();
                                    //2.将消息写到text中
                                    if(isSaveFile){
                                        area.insert("=================================================================================================\n", 0);
                                        String head = poll.topic() +"|"+poll.partition()+ "|" + poll.offset() + "|" + poll.key() +"|"+ Instant.ofEpochMilli(poll.timestamp()).atZone(ZoneId.systemDefault())+ "\n";
                                        String body = FormatUtil.format(poll.value() + "\n");
                                        if(j >= 10000){
                                            area.setText("");//清空,防止内存一处
                                            j = 0;
                                        }
                                        area.insert(body, 0);//每次都写到第一位
                                        area.insert(head, 0);//每次都写到第一位
                                        j++;
                                        System.out.println("---------消费------：" + head);
                                        log.info(head);//add 日志记录
                                        FileService.saveFile(head,poll);
                                        FileService.saveTestDemoFile(poll,operTime);
                                    }else{ //将数据写入数据库表中
                                        TradeO32Service.praseAndInsert(poll,mapper);
                                    }
                                }
                            }
                        }
                    });
                    flush.start();
                }


            }
        });
    }

}
